Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.

...powered by www.netzwerkartist.de...

Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Sprachbeschreibung
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Mathematisches
6 Eigene Klassen schreiben
7 Exceptions
8 Die Funktionsbibliothek
9 Threads und nebenläufige Programmierung
10 Raum und Zeit
11 Datenstrukturen und Algorithmen
12 Dateien und Datenströme
13 Die eXtensible Markup Language (XML)
14 Grafische Oberflächen mit Swing
15 Grafikprogrammierung
16 Das Netz
17 JavaServer Pages und Servlets
18 Verteilte Programmierung mit RMI und Web–Services
19 Applets, Midlets und Sound
20 Datenbankmanagement mit JDBC
21 Reflection und Annotationen
22 Komponenten durch Bohnen
23 Logging und Monitoring
24 Sicherheitskonzepte
25 Java Native Interface (JNI)
26 Dienstprogramme für die Java-Umgebung
A Die Begleit-DVD
Index

Download:
- ZIP, ca. 12,5 MB
Buch bestellen

Website zum Buch
Weblog des Autors
Ihre Meinung?

Spacer
 <<   zurück
Java ist auch eine Insel von Christian Ullenboom
Programmieren mit der Java Standard Edition Version 6
Buch: Java ist auch eine Insel

Java ist auch eine Insel
6., akt. und erw. Aufl., mit DVD
1.454 S., 49,90 Euro
Galileo Computing
ISBN 3-89842-838-9
gp 15 Grafikprogrammierung
  gp 15.1 Grundlegendes zum Zeichnen
    gp 15.1.1 Die paint()-Methode für das AWT-Frame
    gp 15.1.2 Zeichen von Inhalten mit JFrame
    gp 15.1.3 Auffordern zum Neuzeichnen mit repaint()
    gp 15.1.4 Grundbegriffe: Koordinaten, Punkte, Pixel
    gp 15.1.5 Die ereignisorientierte Programmierung ändert Fensterinhalte
    gp 15.1.6 Java 2D API
  gp 15.2 Einfache Zeichenfunktionen
    gp 15.2.1 Linien
    gp 15.2.2 Rechtecke
    gp 15.2.3 Ovale und Kreisbögen
    gp 15.2.4 Polygone und Polylines
  gp 15.3 Zeichenketten schreiben und Fonts
    gp 15.3.1 Zeichenfolgen schreiben
    gp 15.3.2 Die Font-Klasse
    gp 15.3.3 Einen neuen Font aus einem gegebenen Font ableiten
    gp 15.3.4 Zeichensätze des Systems ermitteln
    gp 15.3.5 Neue TrueType-Fonts in Java nutzen
    gp 15.3.6 Font-Metadaten durch FontMetrics
  gp 15.4 Geometrische Objekte
    gp 15.4.1 Die Schnittstelle Shape
    gp 15.4.2 Kreisförmiges
    gp 15.4.3 Kurviges
    gp 15.4.4 Area und die konstruktive Flächengeometrie
    gp 15.4.5 Pfade
  gp 15.5 Farben und die Paint-Schnittstelle, Linientypen
    gp 15.5.1 Zufällige Farbblöcke zeichnen
    gp 15.5.2 Farben mit der Klasse Color
    gp 15.5.3 Die Farben des Systems über SystemColor
    gp 15.5.4 Composite und Xor
    gp 15.5.5 Dicke und Art der Linien von Formen bestimmen
  gp 15.6 Bilder
    gp 15.6.1 Eine Übersicht über die Bilder-Bibliotheken
    gp 15.6.2 Bilder mit ImageIO lesen
    gp 15.6.3 Ein Bild zeichnen
    gp 15.6.4 Programm-Icon/Fenster-Icon setzen
    gp 15.6.5 Splash-Screen
    gp 15.6.6 Bilder im Speicher erzeugen
    gp 15.6.7 Kein Flackern durch Double-Buffering
    gp 15.6.8 Bilder skalieren
    gp 15.6.9 Schreiben mit ImageIO
    gp 15.6.10 Java Image Management Interface (JIMI)
    gp 15.6.11 Pixel für Pixel auslesen und schreiben
    gp 15.6.12 Asynchrones Laden mit getImage() und dem MediaTracker
    gp 15.6.13 VolatileImage
  gp 15.7 Clipping-Operationen
  gp 15.8 Zeichenhinweise durch RenderingHints
  gp 15.9 Transformationen mit einem AffineTransform-Objekt
  gp 15.10 Drucken
    gp 15.10.1 Drucken mit dem einfachen Ansatz
    gp 15.10.2 Ein PrintJob
    gp 15.10.3 Drucken der Inhalte
    gp 15.10.4 Komponenten drucken
    gp 15.10.5 Den Drucker am Parallelport ansprechen
    gp 15.10.6 Bekannte Drucker
  gp 15.11 Grafikverarbeitung ohne grafische Oberfläche
    gp 15.11.1 Xvfb-Server
    gp 15.11.2 Pure Java AWT Toolkit (PJA)
  gp 15.12 Zum Weiterlesen


Galileo Computing

15.5 Farben und die Paint-Schnittstelle, Linientypen  downtop

Die diversen drawXXX()- und fillXXX()-Methoden von Graphics2D berücksichtigen beim Zeichnen Farb- und Texturangaben, die Objekte vom Typ Paint angeben. Paint ist eine Schnittstelle, die unter anderem folgende Klassen aus dem java.awt-Paket implementieren:

  • Color. Repräsentiert Farben und Alpha-Werte (Transparenz).
  • GradientPaintLinearGradientPaint, MultipleGradientPaintRadial GradientPaint. Füllt Formen (Shape-Objekte) mit Farbverläufen.
  • TexturePaint. Füllt Formen mit einer Textur.
  • SystemColor. Repräsentiert Farben, wie sie vom Benutzer in den Systemeinstellungen definiert sind.

Zur Zuweisung eines Paint-Objekt auf dem aktuellen Graphics2D-Kontext dient die Methode setPaint(). Insbesondere für Farben findet sich auch die Methode setColor(). Der Grund für diesen Unterschied ist, dass Paint erst später in Java 2 einzog.

Die Schnittstelle Paint selbst erweitert die Schnittstelle Transparency und gibt auf diese Weise an, dass alles, was gezeichnet werden kann, über Transparenz-Informationen verfügt. Die einzige Methode ist getTransparency(), und sie liefert Werte der Konstanten BITMASK, OPAQUE und TRANSLUCENT.


Galileo Computing

15.5.1 Zufällige Farbblöcke zeichnen  downtop

Um die Möglichkeiten der Farbgestaltung einmal zu beobachten, betrachten wir die Ausgabe eines Programms, das Rechtecke mit wahllosen Farben anzeigt.

Listing 15.11    com/javatutor/insel/ui/graphics/ColorBox.java

package com.javatutor.insel.ui.graphics; 
 
import java.awt.*; 
import java.util.Random; 
import javax.swing.*; 
 
public class ColorBox extends JPanel 
{ 
  private static final long serialVersionUID = -2294685016438617741L; 
  private static final Random r = new Random(); 
 
  @Override 
  protected void paintComponent( Graphics g ) 
  { 
    super.paintComponent( g ); 
 
    for ( int y = 12; y < getHeight() - 25; y += 30 ) 
      for ( int x = 12; x < getWidth() - 25; x += 30 ) 
      { 
        g.setColor( new Color( r.nextInt(256), r.nextInt(256), r.nextInt(256) ) ); 
        g.fillRect( x, y, 25, 25 ); 
        g.setColor( Color.BLACK ); 
        g.drawRect( x - 1, y - 1, 25, 25 ); 
      } 
  } 
 
  public static void main( String[] args ) 
  { 
    JFrame f = new JFrame( "Neoplastizismus" ); 
    f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 
    f.setSize( 300, 300 ); 
    f.add( new ColorBox() ); 
    f.setVisible( true ); 
  } 
}

Abbildung 15.4    Programmierter Neoplastizismus

Das Fenster der Applikation hat eine gewisse Größe, die wir mit size() in der Höhe und Breite abfragen. Anschließend erzeugen wir Blöcke, die mit einer zufälligen Farbe gefüllt sind. fillRect() übernimmt diese Aufgabe. Da die gefüllten Rechtecke immer in der Vordergrundfarbe gezeichnet werden, setzen wir den Zeichenstift durch die Funktion setColor(), die natürlich eine Objektmethode von Graphics ist. Entsprechend gibt es eine korrespondierende Funktion getColor(), die die aktuelle Vordergrundfarbe als Color-Objekt zurückgibt. (Diese Funktion darf nicht mit den Funktionen getColor(String) beziehungsweise getColor-(String, Color) aus der Color-Klasse verwechselt werden.)


abstract class java.awt.Graphics

  • abstract void setColor( Color c ) Setzt die aktuelle Farbe, die dann von den Zeichenfunktionen umgesetzt wird.
  • abstract Color getColor() Liefert die aktuelle Farbe.

Galileo Computing

15.5.2 Farben mit der Klasse Color  downtop

Der Einsatz von Farben und Transparenzen ist in Java-Programmen dank der Klasse Color einfach. Die Klasse stellt einige Konstanten für Standard-Farben und Konstruktoren sowie Anfragefunktionen bereit. Weiterhin gibt es Funktionen, die abgewandelte Color-Objekte liefern – das ist nötig, da Color-Objekte wie String immutable sind.


class java.awt.Color 
implements Paint, Serializable

  • Color( float r, float g, float b ) Erzeugt ein Color-Objekt mit den Grundfarben Rot, Grün und Blau. Die Werte müssen im Bereich 0.0 bis 1.0 liegen, sonst folgt eine IllegalArgumentException.
  • Color( int r, int g, int b ) Erzeugt ein Color-Objekt mit den Grundfarben Rot, Grün und Blau. Die Werte müssen im Bereich 0 bis 255 liegen, sonst folgt eine IllegalArgumentException.
  • Color( int rgb ) Erzeugt ein Color-Objekt aus dem rgb-Wert, der die Farben Rot, Grün und Blau kodiert. Der Rotanteil befindet sich unter den Bits 16 bis 23, der Grünanteil in 8 bis 15 und der Blauanteil in 0 bis 7. Da ein Integer immer 32 Bit breit ist, ist jede Farbe durch ein Byte (8 Bit) repräsentiert. Die Farbinformationen werden nur aus den 24 Bit genommen. Sonstige Werte werden einfach nicht betrachtet und mit einem Alpha-Wert gleich 255 überschrieben.
  • Color( int r, int g, int b, int a )
  • Color( float r, float g, float b, float a ) Erzeugt ein Color-Objekt mit Alpha-Wert für Transparenz.
  • static Color decode( String nm ) throws NumberFormatException Liefert die Farbe von nm. Die Zeichenkette ist hexadezimal als 24-Bit-Integer kodiert, etwa #00AAFF. Eine Alternative ist new Color( Integer.parseInt(colorHexString, 16) );

Hinweis Menschen unterscheiden Farben gemäß den drei Eigenschaften Farbton, Helligkeit und Sättigung. Die menschliche Farbwahrnehmung kann etwa zweihundert Farbtöne unterscheiden. Diese werden durch die Wellenlänge des Lichts bestimmt. Die Lichtintensität und Empfindlichkeit unserer Rezeptoren lässt uns etwa fünfhundert Helligkeitsstufen unterscheiden. Bei der Sättigung handelt es sich um eine Mischung mit weißem Licht. Hier erkennen wir etwa zwanzig Stufen. Unser visuelles System kann somit etwa zwei Millionen (200 × 500 × 20) Farbnuancen unterscheiden.

Farbanteile zurückgeben

Mitunter müssen wir den umgekehrten Weg gehen und von einem gegebenen Color-Objekt wieder die Rot-, Grün- oder Blau-Anteile extrahieren. Dies ist einfach, und die Funktionsbibliothek bietet Entsprechendes an:


class java.awt.Color 
implements Paint, Serializable

  • int getRed(), int getGreen(), int getBlue() Liefert Rot-, Grün- und Blau-Anteile des Farbobjekts im Bereich von 0 bis 255.
  • int getAlpha() Gibt den Alpha-Anteil zurück.
  • int getRGB() Gibt die RGB-Farbe zurück. Die Bits 24 – 31 repräsentieren den Alpha-Wert, 16 – 23 stehen für Rot, 8 – 15 für Grün und 0 – 7 für Blau.

Vordefinierte Farben

Wenn wir Farben benutzen wollen, sind schon viele Werte vordefiniert, wie Color.WHITE. In der Klasse jawa.awt.Color sind dazu viele Zeilen der Form

/** 
 * The color white. 
 */ 
public final static Color WHITE = new Color( 255, 255, 255 );

platziert. Die folgende Tabelle zeigt die deklarierten Konstanten inklusive Wertebelegung für die Farbtupel:


Tabelle 15.1    Farbanteile für die vordefinierten Standardfarben
Farbname Rot Grün Blau
WHITE 255 255 255
BLACK 0 0 0
RED 255 0 0
GREEN 0 255 0
BLUE 0 0 255
YELLOW 255 255 0
MAGENTA 255 0 255
CYAN 0 255 255
PINK 255 175 175
ORANGE 255 200 0
LIGHT_GRAY 192 192 192
DARK_GRAY 64 64 64

Alle Farbnamen gibt es auch kleingeschrieben. Zwar stammt von Sun die Namenskonvention, dass Konstanten großgeschrieben werden, aber bei den Farbnamen wurde das erst in Java 1.4 nachgeholt – sieben Jahre später.

Einen helleren oder dunkleren Farbton wählen

Zwei besondere Funktionen sind brighter() und darker(). Sie liefern ein Farbobjekt zurück, das jeweils eine Farbnuance heller beziehungsweise dunkler ist. Die Graphics-Funktion draw3DRect() nutzt zum Beispiel diese beiden Funktionen, um die Ränder in hellerem und dunklerem Farbton zu zeichnen. Wie viele andere Funktionen aus der Color-Klasse sind auch die Routinen nicht nativ implementiert:

public Color brighter() { 
    return new Color(Math.min((int)(getRed()  *(1/FACTOR)), 255), 
                     Math.min((int)(getGreen()*(1/FACTOR)), 255), 
                     Math.min((int)(getBlue() *(1/FACTOR)), 255)); 
} 
public Color darker() { 
    return new Color(Math.max((int)(getRed()  *FACTOR), 0), 
                     Math.max((int)(getGreen()*FACTOR), 0), 
                     Math.max((int)(getBlue() *FACTOR), 0)); 
}

FACTOR ist eine finale Konstante, die durch 0,7 vordefiniert ist. Sie lässt sich also nicht ändern.


class java.awt.Color 
implements Paint, Serializable

  • Color brighter() Gibt einen helleren Farbton zurück.
  • Color darker() Gibt einen dunkleren Farbton zurück.

Farbveränderung mit Nullanteilen

Bei den Farbwerten müssen wir nun die Zusammensetzung aus Rot, Grün und Blau bedenken. Ein voller Wert ist mit 255 belegt. Die Berechnung kann diesen Wert noch modifizieren. Doch ist ein Eintrag mit 0 belegt, so erkennen wir aus der Berechnung, dass der Wert bei null bleiben wird. Daher sollten wir bedenken, was bei reinen Farben (wie etwa Rot) durch ein brighter() passiert. Ein reiner Rotton kann sich zwar in der Helligkeit ändern, aber ein Color.RED.brighter() liefert immer noch Color.RED.

System.out.println( Color.RED.brighter() ); // java.awt.Color[r=255,g=0,b=0] 
System.out.println( Color.RED.darker() );   // java.awt.Color[r=178,g=0,b=0]

Es ist also nicht so, dass bei brighter() die Farben näher an Weiß herankommen und bei darker() näher an Schwarz.

Um also echte Helligkeitsveränderungen zu bekommen, müssen wir die Farben vorher umrechnen. Hierzu bieten sich andere Farbräume an, wie beispielsweise der HSB-Raum, in dem wir Komponenten für die Helligkeit haben. RGBtoHSB() gibt ein Feld mit den Werten für Hue, Saturation und Brightness für ein Tripel von Rot-, Grün- und Blau-Werten zurück. Nach einer Veränderung der Helligkeit können wir diesen Farbraum wieder mit HSBtoRGB() zurückkonvertieren.

Farbmodelle HSB und RGB

Zwei Farbmodelle sind in der Computergrafik geläufig. Das RGB-Modell, bei dem die Farben durch einen Rot-, Grün- und Blau-Anteil definiert werden, oder das HSB-Modell, das die Farben durch Grundton (Hue), Farbsättigung (Saturation) und Helligkeit (Brightness) definiert. Die Farbmodelle können die gleichen Farben beschreiben und ineinander umgerechnet werden.


class java.awt.Color 
implements Paint, Serializable

  • static int HSBtoRGB( float hue, float saturation, float brightness ) Aus einem HSB-kodierten Farbwert wird ein RBG-Farbwert.
  • static float[] RGBtoHSB( int r, int g, int b, float[] hsbvals ) Verlangt ein Array hsbvals zur Aufnahme von HSB, in dem die Werte gespeichert werden sollen. Das Array kann null sein und wird somit angelegt. Das Feld wird zurückgegeben.
  • static Color getHSBColor( float h, float s, float b ) Erzeugt Color-Objekt mit Werten aus dem HSB-Modell.

Die Implementierung von getHSBColor() ist ein Witz:

public static Color getHSBColor(float h, float s, float b) { 
  return new Color(HSBtoRGB(h, s, b)); 
}

Galileo Computing

15.5.3 Die Farben des Systems über SystemColor  downtop

Bei eigenen Java-Programmen ist es wichtig, dass diese sich so perfekt wie möglich in die Reihe der anderen Host-Programme einreihen, ohne großartig aufzufallen. Dafür muss ein Fenster die globalen Einstellungen wie den Zeichensatz und die Farben kennen. Für die Systemfarben gibt es die Klasse SystemColor, die alle Farben einer grafischen Oberfläche auf symbolische Konstanten abbildet. Besonders praktisch ist dies bei Änderungen von Farben während der Laufzeit. Über diese Klasse können immer die aktuellen Werte eingeholt werden, denn ändert sich beispielsweise die Hintergrundfarbe der Laufleisten, ändert sich damit auch der RGB-Wert. Die Systemfarben sind Konstanten von SystemColor und werden mit der Funktion getRGB() in eine Ganzzahl umgewandelt.

Die Klasse deklariert die folgenden statischen finalen Variablen: [Mal wieder verstößt Sun gegen die eigenen Namenskonventionen. Die finalen Variablen – Konstanten – sollten großgeschrieben werden. Das geht für die SystemColor-Objekte aber nicht, da es alle Bezeichnernamen schon in groß gibt, und zwar für Variablen vom Typ Byte, die Verweise in eine interne Tabelle darstellen. ]


class java.awt.SystemColor 
implements Serializable


Tabelle 15.2    Konstanten der Systemfarben
SystemColor Welche Farbe darauf anspricht
desktop Farbe des Desktop-Hintergrunds
activeCaption Hintergrundfarben für Text im Fensterrahmen
activeCaptionText Farbe für Text im Fensterrahmen
activeCaptionBorder Rahmenfarbe für Text im Fensterrahmen
inactiveCaption Hintergrundfarbe für inaktiven Text im Fensterrahmen
inactiveCaptionText Farbe für inaktiven Text im Fensterrahmen
inactiveCaptionBorder Rahmenfarbe für inaktiven Text im Fensterrahmen
window Hintergrundfarbe der Fenster
windowBorder Rahmenfarbe der Fenster
windowText Textfarbe für Fenster
menu Hintergrundfarbe für Menüs
menuText Textfarbe für Menüs
text Hintergrundfarbe für Textkomponenten
textText Textfarbe für Textkomponenten
textHighlight Hintergrundfarbe für hervorgehobenen Text
textHighlightText Farbe des Texts, wenn dieser hervorgehoben ist
textInactiveText Farbe für inaktiven Text
control Hintergrundfarbe für Kontrollobjekte
controlText Textfarbe für Kontrollobjekte
controlHighlight Normale Farbe, mit der Kontrollobjekte hervorgehoben werden
controlLtHighlight Hellere Farbe, mit der Kontrollobjekte hervorgehoben werden
controlShadow Normale Hintergrundfarbe für Kontrollobjekte
controlDkShadow Dunklerer Schatten für Kontrollobjekte
scrollbar Hintergrundfarbe der Schieberegler
info Hintergrundfarbe der Hilfe
infoText Textfarbe der Hilfe

Um die Systemfarbe in eine brauchbare Variable zu konvertieren, gibt es die getRGB()-Funktion. So erzeugt new Color((SystemColor.window).getRGB()) ein Color-Objekt in der Farbe des Fensters.


final class java.awt.SystemColor 
implements Serializable

  • int getRGB() Liefert den RGB-Wert der Systemfarbe als Ganzzahl kodiert.

Um zu sehen, welche Farben auf dem laufenden System aktiv sind, formulieren wir ein Programm, das eine kleine Textzeile in der jeweiligen Farbe angibt. Da wir auf die internen Daten nicht zugreifen können, müssen wir ein Farbfeld mit SystemColor-Objekten aufbauen.

Abbildung 15.5    Die Systemfarben unter einer Windows-Konfiguration

Listing 15.12    com/javatutor/insel/ui/graphics/SystemColors.java

package com.javatutor.insel.ui.graphics; 
 
import java.awt.*; 
import javax.swing.*; 
 
class SystemColors extends JPanel 
{ 
  private String[] systemColorString = { 
    "desktop", "activeCaption", "activeCaptionText", 
    "activeCaptionBorder", "inactiveCaption", 
    "inactiveCaptionText", "inactiveCaptionBorder", 
    "window", "windowText", "menu", "menuText", 
    "text", "textText", "textHighlight", 
    "textHighlightText","textInactiveText", 
    "control", "controlText", "controlHighlight", 
    "controlLtHighlight", "controlShadow", 
    "controlDkShadow", "scrollbar", 
    "info", "infoText" 
  }; 
  private SystemColor[] systemColor = { 
    SystemColor.desktop, 
    SystemColor.activeCaption, 
    SystemColor.activeCaptionText, 
    SystemColor.activeCaptionBorder, 
    SystemColor.inactiveCaption, 
    SystemColor.inactiveCaptionText, 
    SystemColor.inactiveCaptionBorder, 
    SystemColor.window, 
    SystemColor.windowText, 
    SystemColor.menu, 
    SystemColor.menuText, 
    SystemColor.text, 
    SystemColor.textText, 
    SystemColor.textHighlight, 
    SystemColor.textHighlightText, 
    SystemColor.textInactiveText, 
    SystemColor.control, 
    SystemColor.controlText, 
    SystemColor.controlHighlight, 
    SystemColor.controlLtHighlight, 
    SystemColor.controlShadow, 
    SystemColor.controlDkShadow, 
    SystemColor.scrollbar, 
    SystemColor.info, 
    SystemColor.infoText 
  }; 
 
  @Override 
  protected void paintComponent( Graphics g ) 
  { 
    super.paintComponent( g ); 
    g.setFont( new Font( "Dialog", Font.BOLD, 12 ) ); 
    for ( int i = 0; i < systemColorString.length; i++ ) { 
      g.setColor( new Color( systemColor[i].getRGB() ) ); 
      g.drawString( systemColorString[i], 20, 60 + (i*13) ); 
    } 
  } 
 
  public static void main( String[] args ) 
  { 
    JFrame f = new JFrame(); 
    f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 
    f.setSize ( 170, 400 ); 
    f.add( new SystemColors() ); 
    f.setVisible( true ); 
  } 
}

Galileo Computing

15.5.4 Composite und Xor  downtop

Ein Composite ist eine Zusammenfügung der zu zeichnenden Elemente und des Hintergrunds. Auf dem Graphics2D-Objekt setzt setComposite(Composite) den Modus, wobei bisher AlphaComposite die einzige direkte Implementierung der Schnittstelle Composite ist. Ein AlphaComposite-Objekt bestimmt, wie die Überblendung aussehen soll.


Beispiel Zeichne ein Bild image mit dem Alpha-Wert alpha:
Graphics2D g2 = (Graphics2D) g; 
g2.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha) ); 
g2.drawImage( image, 0, 0, this );

Die zweite Einstellung, wie Farben auf das Ziel wirken, bestimmt der Xor-Modus, der ein spezieller Composite ist: die Berechnung gibt die API-Dokumentation von Sun an.


abstract class java.awt.Graphics

  • abstract void setComposite( Composite comp ) Setzt das Composite-Objekt, das die Verschmelzung der folgenden Zeichenoperationen mit dem Hintergrund definiert.
  • abstract void setXORMode( Color c ) Setzt die Pixel-Operation auf Xor. Abwechselnde Punkte werden in der aktuellen Farbe und der mit dieser Funktion gesetzten Xor-Farbe gesetzt.

Galileo Computing

15.5.5 Dicke und Art der Linien von Formen bestimmen  toptop

Vor dem Zeichnen sammelt das Grafiksystem die Objekte in einem Kontext. Er bestimmt für die Form den Zeichenbereich (engl. clipping), die Transformationen, die Komposition von Objekten und die Farben und Muster. Die Dicke (engl. width) einer Form, sowie die Stelle, wo ein Liniensegment beginnt und endet (engl. end caps), die Art, wie die Linien verbunden werden (engl. line joins), und ein Linien-Pattern (engl. dash attributes) bestimmt ein Objekt vom Typ Stroke, das setStroke() setzt. BasicStroke implementiert die Schnittstelle Stroke.


Beispiel Zeichne die folgenden Formen mit einer Dicke von zehn Pixel:
Stroke stroke = new BasicStroke( 10 ); 
g2.setStroke( stroke );

Linienenden (end caps)

Besonders bei breiten Linien ist es interessant, wie eine allein stehende Linie endet. Sie kann einfach aufhören oder auch abgerundet sein. Die Konstanten CAP_BUTT, CAP_ROUND und CAP_SQUARE bestimmen diesen Linienende-Typ.

Linienverbindungen (line joins)

Wenn Linien nicht alleine stehen, sondern etwa wie in einem Rechteck verbunden sind, stellt sich eine ähnliche Frage, wie diese Verbindungspunkte gezeichnet werden. Das bestimmen ebenfalls drei Konstanten:

  • JOIN_MITER schließt die Linien so ab, dass sie senkrecht aufeinander stehen.
  • JOIN_ROUND rundet die Ecken ab.
  • JOIN_BEVEL zieht eine Linie zwischen den beiden äußeren Endpunkten.

Von BasicStroke gibt es nur einen Konstruktor, der Linienenden und Linienverbindungen gleichzeitig bestimmt haben möchte.


Beispiel Unterschiedliche Linienenden.

Listing 15.13    com/javatutor/insel/ui/g2d/EndCapsDemo.java, paintComponent()

@Override 
protected void paintComponent( Graphics g ) 
{ 
  Graphics2D g2 = (Graphics2D) g; 
 
  g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING, 
                       RenderingHints.VALUE_ANTIALIAS_ON); 
 
  g2.setStroke( new BasicStroke( 20, 
                  BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER ) ); 
  g2.drawLine( 30, 50, 200, 50 ); 
 
  g2.setStroke( new BasicStroke( 20, 
                  BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER ) ); 
  g2.drawLine( 30, 150, 200, 150 ); 
 
  g2.setStroke( new BasicStroke( 20, 
                  BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER ) ); 
  g2.drawLine( 30, 100, 200, 100 ); 
}

Falls der Typ der Linienverbindungen nicht JOIN_MITER ist, bestimmt die Variable miterlimit, wie weit die Linien nach außen gezogen sind.

Abbildung 15.6    Unterschiedliche Linienenden

Listing 15.14    com/javatutor/insel/ui/g2d/MiterlimitDemo.java, paintComponent()

@Override 
protected void paintComponent( Graphics g ) 
{ 
  Graphics2D g2 = (Graphics2D) g; 
 
  g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING, 
                       RenderingHints.VALUE_ANTIALIAS_ON); 
 
  BasicStroke stroke = new BasicStroke( 15, 
    BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 
    1 );  // Miterlimit = 15 
 
  g2.setStroke( stroke ); 
 
  g2.draw( new Rectangle2D.Float( 50, 50, 50, 50 ) ); 
 
  stroke = new BasicStroke( 15, 
    BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 
    10 );  // Miterlimit = 15 
 
  g2.setStroke( stroke ); 
 
  g2.draw( new Rectangle2D.Float( 150, 50, 50, 50 ) ); 
}

Abbildung 15.7    Unterschiedliche Miterlimits

Füllmuster (dash)

Auch die Muster, mit denen die Linien oder Kurven gezeichnet werden, lassen sich ändern. Dazu erzeugen wir vorher ein Feld und übergeben dies einem Konstruktor. Damit auch die Muster abgerundet werden, muss CAP_ROUND gesetzt sein. Die folgenden Zeilen erzeugen ein Rechteck mit einem einfachen Linienmuster. Es sollen zehn Punkte gesetzt und zwei Punkte frei sein.

Listing 15.15    com/javatutor/insel/ui/g2d/DashDemo.java, Ausschnitt

float[] dash = { 10, 2 }; 
BasicStroke stroke = new BasicStroke( 2, 
  BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 
  1, 
  dash, 0 ); 
 
g2.setStroke( stroke ); 
g2.draw( new Rectangle2D.Float( 50, 50, 50, 50 ) );

Als letztes Argument am Konstruktor von BasicStroke hängt noch eine Verschiebung. Dieser Parameter bestimmt, wie viele Pixel im Muster übersprungen werden sollen. Geben wir dort für unser Beispiel etwa 10 an, so beginnt die Linie gleich mit zwei nicht gesetzten Pixeln. Eine 12 ergibt eine Verschiebung wieder an den Anfang. Bei nur einer Zahl im Feld ist der Abstand der Linien und die Breite einer Linie genauso lang, wie diese Zahl angibt. Bei gepunkteten Linien ist das Feld also 1. Hier eignet sich ein anonymes Feld ganz gut, wie die nächsten Zeilen zeigen:

stroke = new BasicStroke( 1, 
  BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 
  1, new float[]{ 1 }, 0 );

Bei feinen Linien sollten wir das Weichzeichnen besser ausschalten.

Abbildung 15.8    Zwei Linienmuster



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.





 <<   zurück



Copyright © Galileo Press 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte v